package main

import (
	"fmt"
	"sync"
)

// select + channel
// 用 select 语句处理多个 channel，随机 选择可用通道做收发操作
// 将失效通道置为 nil （阻塞，不可用），用作结束判断

func main() {
	var wg sync.WaitGroup
	wg.Add(2)

	cha, chb := make(chan int), make(chan int)

	// recv
	go func() {
		defer wg.Done()

		for {
			x := 0
			ok := false

			fmt.Printf("x:%p, ok:%p\n", &x, &ok)

			select {

			case x, ok = <-cha: // = 是将接收的值赋值给外层的 x，ok
				// case x, ok := <-cha: // := 声明新变量，遮蔽外层的 x,ok
				if !ok {
					cha = nil
				}

				fmt.Printf("<-cha case --- x:%p, ok:%p\n", &x, &ok)
			case x, ok = <-chb:
				if !ok {
					chb = nil
				}
				fmt.Printf("<-chb case --- x:%p, ok:%p\n", &x, &ok)
				// default:
				// 	fmt.Println("default x=", x)
			}

			if (cha == nil) && (chb == nil) {
				return
			}

			fmt.Println("loop end, x=", x)
		}
	}()

	// send
	go func() {
		defer wg.Done()

		defer close(cha)
		defer close(chb)

		for i := 0; i < 10; i++ {
			// random
			select {
			case cha <- i:
			case chb <- i * 10:
			}
		}
	}()

	wg.Wait()

}
